﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Simple.Common.Authentication;
using Simple.Services.System.FileInfo;

namespace Simple.Services.System
{
    /// <summary>
    /// 服药登记
    /// </summary>
    public class MedicationRegisterService : BusinessBaseService
    {
        private readonly SimpleDbContext _context;
        private readonly FileInfoService _fileInfoService;
        public MedicationRegisterService(ISimpleService services,
            SimpleDbContext context,
            FileInfoService fileInfoService) : base(services)
        {
            _context = context;
            _fileInfoService = fileInfoService;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <param name="IsParent"></param>
        /// <returns></returns>
        public async Task<PageResultModel<MedicationRegisterDto>> GetPage(MedicationRegisterPageInput input, bool IsParent = false)
        {
            var result = new PageResultModel<MedicationRegisterDto>();
            var query = (await OrganizationFilter(_context.Set<MedicationRegister>())).AsQueryable();
            if (IsParent)
            {
                var childId = _currentUser?.FindClaimValue(SimpleClaimTypes.ChildId);
                if (!string.IsNullOrWhiteSpace(childId))
                {
                    query = query.Where(p => p.ChildId.ToString() == childId);
                }
                else
                {
                    return result;
                }
            }
            else
            {
                if (input.ClassId.HasValue)
                {
                    query = query.Where(p => p.ClassId == input.ClassId);
                }
                if (input.StartTime.HasValue)
                {
                    query = query.Where(p => p.MedicationTime.Date >= input.StartTime.Value.Date);
                }
                if (input.EndTime.HasValue)
                {
                    query = query.Where(p => p.MedicationTime.Date <= input.EndTime.Value.Date);
                }
            }
            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.OrderByDescending(u => u.CreatedTime).Page(input.PageNo, input.PageSize);
            var lstEntity = await query.ToListAsync();
            var lstDto = MapperHelper.Map<List<MedicationRegisterDto>>(lstEntity);
            lstDto = Completion(lstDto);
            result.Rows = lstDto;

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }

        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<MedicationRegisterExtendDto> Get(Guid id)
        {
            var entity = await _context.Set<MedicationRegister>().Include(p => p.Images).FirstOrDefaultAsync(p => p.Id == id);
            if (entity == null)
            {
                throw AppResultException.Status500InternalServerError("没有找到该服药登记");
            }
            var dto = MapperHelper.Map<MedicationRegisterDto>(entity);
            var result = MapperHelper.Map<MedicationRegisterExtendDto>(Completion(new List<MedicationRegisterDto> { dto }).FirstOrDefault());
            result.AutographImg = entity.AutographImg;
            if (entity.Images != null && entity.Images.Any())
            {
                result.DrugsImage = entity?.Images;
            }
            var lstRecode = new List<string>() { $"{entity?.CreatedTime.Value.ToString("yyyy-MM-dd HH:mm")} {result.RelationshipStr}{result.ParentName}登记服药" };
            if (entity.ConfirmedTime.HasValue)
            {
                var teacher = _context.Set<SysUser>().FirstOrDefault(p => p.Id == entity.TeacherId);
                lstRecode.Add($"{entity?.ConfirmedTime.Value.ToString("yyyy-MM-dd HH:mm")} {teacher?.Name}老师确认服药登记");
            }
            if (entity.RejectTime.HasValue)
            {
                var teacher = _context.Set<SysUser>().FirstOrDefault(p => p.Id == entity.TeacherId);
                lstRecode.Add($"{entity?.RejectTime.Value.ToString("yyyy-MM-dd HH:mm")} {teacher?.Name}老师驳回服药登记，理由：{entity?.RejectReason}");
            }
            if (entity.RescindedTime.HasValue)
            {
                lstRecode.Add($"{entity?.RescindedTime.Value.ToString("yyyy-MM-dd HH:mm")} {result.RelationshipStr}{result.ParentName}撤回服药登记");
            }
            return result;
        }

        /// <summary>
        /// 登记
        /// </summary>
        /// <returns></returns>
        public async Task<bool> Register(RegisterInput input)
        {
            if (_currentUser == null)
            {
                throw AppResultException.Status409Conflict("登录已过期,请重新登录!");
            }
            var userId = _currentUser?.FindClaimValue(SimpleClaimTypes.UserId);
            var relationship = _currentUser?.FindClaimValue(SimpleClaimTypes.Relationship);
            var childId = _currentUser?.FindClaimValue(SimpleClaimTypes.ChildId);
            var claccId = _currentUser?.FindClaimValue(SimpleClaimTypes.ClassesId);
            var images = new List<MedicationRegisterImage>();
            if (input.ImageIdList != null)
            {
                var files = await _fileInfoService.GetFilesByIdListAsync(input.ImageIdList);
                images = files?.Select(file => new MedicationRegisterImage { FiledId = file.Id, FileName = file.FileName, FileSize = file.FileSize ?? String.Empty })?.ToList();
            }
            var entity = MapperHelper.Map<MedicationRegister>(input);
            entity.ChildId = new Guid(childId);
            entity.ClassId = new Guid(claccId);
            entity.ParentId = new Guid(userId);
            entity.Relationship = int.Parse(relationship);
            entity.Images = images;

            await _context.AddAsync(entity);
            var rte = await _context.SaveChangesAsync();
            return rte > 0;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Update(RegisterInput input)
        {
            var entity = await _context.Set<MedicationRegister>().Include(p => p.Images).FirstOrDefaultAsync(p => p.Id == input.Id);
            if (entity == null)
            {
                throw AppResultException.Status500InternalServerError("没有找到该服药登记");
            }
            if (entity.State != EnumMedicationRegisterState.ToBeConfirmed)
            {
                throw AppResultException.Status500InternalServerError("只能修改'待确认'的服药登记");
            }
            MapperHelper.Map(input, entity);
            var images = new List<MedicationRegisterImage>();
            if (input.ImageIdList != null)
            {
                var files = await _fileInfoService.GetFilesByIdListAsync(input.ImageIdList);
                images = files?.Select(file => new MedicationRegisterImage { FiledId = file.Id, FileName = file.FileName, FileSize = file.FileSize ?? String.Empty })?.ToList();
            }
            if (entity.Images != null)
            {
                _context.RemoveRange(entity.Images);
            }
            entity.Images = images;
            _context.Update(entity);
            int ret = await _context.SaveChangesAsync();
            return ret > 0;
        }

        /// <summary>
        /// 操作
        /// </summary>
        /// <returns></returns>
        public async Task<bool> Action(Guid id, EnumMedicationRegisterState type, string contet)
        {
            if (_currentUser == null)
            {
                throw AppResultException.Status409Conflict("登录已过期,请重新登录!");
            }
            var entity = await _context.Set<MedicationRegister>().FirstOrDefaultAsync(p => p.Id == id);
            if (entity == null)
            {
                throw AppResultException.Status500InternalServerError("没有找到该服药登记");
            }
            switch (type)
            {
                case EnumMedicationRegisterState.Confirmed:
                    if (entity.State != EnumMedicationRegisterState.ToBeConfirmed)
                    {
                        throw AppResultException.Status500InternalServerError("只能确认'待确认'的服药登记");
                    }
                    var userId = _currentUser?.FindClaimValue(SimpleClaimTypes.UserId);
                    entity.TeacherId = new Guid(userId);
                    entity.ConfirmedTime = DateTime.Now;
                    entity.State = EnumMedicationRegisterState.Confirmed;
                    break;
                case EnumMedicationRegisterState.Rescinded:
                    entity.RescindedTime = DateTime.Now;
                    entity.State = EnumMedicationRegisterState.Rescinded;
                    break;
                case EnumMedicationRegisterState.Reject:
                    if (entity.State != EnumMedicationRegisterState.ToBeConfirmed)
                    {
                        throw AppResultException.Status500InternalServerError("只能驳回'待确认'的服药登记");
                    }
                    entity.RejectTime = DateTime.Now;
                    entity.RejectReason = contet;
                    entity.State = EnumMedicationRegisterState.Reject;
                    break;
                default:
                    break;
            }
            _context.Update(entity);
            int ret = await _context.SaveChangesAsync();
            return ret > 0;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsync(IEnumerable<Guid> ids)
        {
            var lstTask = await _context.Set<MedicationRegister>()
                .Where(u => ids.Contains(u.Id))
                .ToListAsync();

            _context.RemoveRange(lstTask);
            return await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 完善
        /// </summary>
        /// <param name="lstDto"></param>
        /// <returns></returns>
        public List<MedicationRegisterDto> Completion(List<MedicationRegisterDto> lstDto)
        {
            return (from m in lstDto
                    join c in _context.Set<Childrens>().AsQueryable() on m.ChildId equals c.Id into mc
                    join cl in _context.Set<SysClasses>().AsQueryable() on m.ClassId equals cl.Id into mcl
                    join p in _context.Set<Parent>().AsQueryable() on m.ParentId equals p.Id into mp
                    from lmc in mc.DefaultIfEmpty()
                    from lmcl in mcl.DefaultIfEmpty()
                    from lmp in mp.DefaultIfEmpty()
                    select new MedicationRegisterDto
                    {
                        Id = m.Id,
                        ChildId = m.ChildId,
                        ChildName = lmc.Name,
                        ChildImgId = lmc.ImgId,
                        MedicationTime = m.MedicationTime,
                        ClassId = m.ClassId,
                        ClassName = lmcl.Name,
                        Name = m.Name,
                        Explain = m.Explain,
                        ParentId = m.ParentId,
                        ParentName = lmp.Name,
                        Relationship = m.Relationship,
                        State = m.State,
                        CreatedTime = m.CreatedTime,
                        RejectReason = m.RejectReason,
                    }).ToList();
        }
    }
}
